package com.cskaoyan.javase.oop3._0abstract._3exercise;

/**
 * @description: 小练习
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 我们正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 *
 * 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 * 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 * 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 * 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 *
 * 请使用所学的知识设计该员工系统
 * 要求类中提供必要的方法进行属性访问（description）
 *
 * 肯定需要继承,关键字是怎么写继承体系:
 *      1,可以考虑直接把普通员工作为父类,这个时候它就不能是抽象类了,这么做实现需求是可以的,但是有一定的缺点:
 *          a,在案例的程序中是存在普通员工对象的,
 *              如果把普通员工类作为其它员工的父类,这就意味着普通员工类的修改会影响别的类,这肯定是不好的
 *              (改善这一点,就需要找一个不能创建对象的类来作为父类,这样它的修改就可以针对全体员工了)
 *          b,普通方法在继承中无法起到"占位"的作用,子类可以自由选择是否重写,这个自由不需要给它
 *              所以我们需要抽象类中的抽象方法起"占位"作用,这样子类就必须重写方法
 *
 *      2,定义一个抽象的员工类,然后让其它三个类继承它即可
 *
 * 要求类中提供必要的方法进行属性访问（description）
 *      该方法可以在抽象类中提供普通成员方法的默认实现,然后在子类中可以选择直接继承使用,也可以选择重写
 *
 *
 *
 */

public class Demo {
    public static void main(String[] args) {
        //创建对象,逐一实验
        AbstractStaff as;
        as = new NormalStaff("张三", 10, 10000);
        System.out.println(as.salary);
        as.work();
        as.printFields();

        as = new Coder("李四", 20, 20000);
        as.work();
        //as引用不能直接访问子类独有成员,想要访问必须强转
        if (as instanceof Coder) ((Coder) as).overTimeWork();
        as.printFields();

        as = new Manager("麻子", 1, 30000, 100000);
        as.work();
        if (as instanceof Manager) System.out.println(((Manager) as).bonus);
        as.printFields();

    }
}

//抽象员工类
abstract class AbstractStaff {
    //共有的成员变量
    String name;
    int id;
    double salary;

    //共有的方法
    public abstract void work();

    public AbstractStaff() {
    }

    public AbstractStaff(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    //打印属性的方法
    public void printFields() {
        System.out.println("姓名为:" + name + "的员工,他的工号是:" + id + "他的工资是:" + salary);
    }
}

//普通员工类
class NormalStaff extends AbstractStaff {
    @Override
    public void work() {
        System.out.println("负责杂项工作");
    }

    public NormalStaff() {
    }

    public NormalStaff(String name, int id, double salary) {
        super(name, id, salary);
    }
}

//程序员类
class Coder extends AbstractStaff {

    @Override
    public void work() {
        System.out.println("负责技术开发");
    }

    //额外的工作
    public void overTimeWork() {
        System.out.println("996");
    }

    public Coder() {
    }

    public Coder(String name, int id, double salary) {
        super(name, id, salary);
    }
}

//经理类
class Manager extends AbstractStaff {

    //额外的属性
    double bonus;//奖金

    @Override
    public void work() {
        System.out.println("负责统筹规划");
    }

    public Manager() {
    }

    public Manager(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    //重写打印属性的方法

    @Override
    public void printFields() {
        System.out.println("姓名为:" + name + "的员工,他的工号是:" + id + "他的工资是:" + (salary + bonus));
    }
}